package com.gzc.just.play.last.war.common.handler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.List;
import java.util.ArrayList;

/**
 * 战斗会话类，封装一个战斗的游戏逻辑处理
 * 每个战斗会话对应一个虚拟线程
 */
public class BattleSession {
    private static final Logger logger = LoggerFactory.getLogger(BattleSession.class);
    
    private final long battleId;
    private final String battleName;
    private final Thread processingThread;
    private final AtomicBoolean running;
    
    // 消息队列，线程安全
    private final ConcurrentLinkedQueue<BattleMessageContext> messageQueue = new ConcurrentLinkedQueue<>();
    
    // 战斗参与者列表
    private final ConcurrentHashMap<Long, BattlePlayer> players = new ConcurrentHashMap<>();
    
    // 战斗状态
    private volatile BattleState battleState = BattleState.PREPARING;
    
    // 战斗创建时间
    private final long creationTime = System.currentTimeMillis();
    
    // 战斗最大玩家数
    private final int maxPlayers = 10; // 默认最大玩家数为10
    
    // 战斗ID生成器
    private static final AtomicLong battleIdGenerator = new AtomicLong(1000);
    
    /**
     * 战斗消息上下文
     */
    public static class BattleMessageContext {
        private final long playerId;
        private final int messageId;
        private final byte[] messageBytes;
        private final long timestamp;
        
        public BattleMessageContext(long playerId, int messageId, byte[] messageBytes) {
            this.playerId = playerId;
            this.messageId = messageId;
            this.messageBytes = messageBytes;
            this.timestamp = System.currentTimeMillis();
        }
        
        public long getPlayerId() {
            return playerId;
        }
        
        public int getMessageId() {
            return messageId;
        }
        
        public byte[] getMessageBytes() {
            return messageBytes;
        }
        
        public long getTimestamp() {
            return timestamp;
        }
    }
    
    /**
     * 战斗参与者信息
     */
    public static class BattlePlayer {
        private final long playerId;
        private final String playerName;
        private final long joinTime;
        private volatile boolean ready = false;
        
        public BattlePlayer(long playerId, String playerName) {
            this.playerId = playerId;
            this.playerName = playerName;
            this.joinTime = System.currentTimeMillis();
        }
        
        public long getPlayerId() {
            return playerId;
        }
        
        public String getPlayerName() {
            return playerName;
        }
        
        public long getJoinTime() {
            return joinTime;
        }
        
        public boolean isReady() {
            return ready;
        }
        
        public void setReady(boolean ready) {
            this.ready = ready;
        }
    }
    
    /**
     * 战斗状态枚举
     */
    public enum BattleState {
        PREPARING,    // 准备中
        IN_PROGRESS,  // 进行中
        PAUSED,       // 暂停中
        FINISHED,     // 已结束
        ABORTED       // 已中止
    }
    
    /**
     * 构造函数
     * @param battleId 战斗ID
     * @param battleName 战斗名称
     */
    public BattleSession(long battleId, String battleName) {
        this.battleId = battleId;
        this.battleName = battleName;
        this.running = new AtomicBoolean(false);
        
        // 创建并启动专用的虚拟线程
        this.processingThread = Thread.ofVirtual()
                .name("BattleSession-" + battleId)
                .start(this::processBattleLogicLoop);
        
        // 设置为守护线程
        this.processingThread.setDaemon(true);
    }
    
    /**
     * 创建新的战斗会话
     * @param battleName 战斗名称
     * @return 新的战斗会话
     */
    public static BattleSession createBattle(String battleName) {
        long battleId = battleIdGenerator.incrementAndGet();
        return new BattleSession(battleId, battleName);
    }
    
    /**
     * 启动战斗会话
     */
    public void start() {
        running.set(true);
        battleState = BattleState.PREPARING;
        logger.info("Started battle session: {} ({}) in thread: {}", 
                   battleId, battleName, Thread.currentThread().getName());
    }
    
    /**
     * 停止战斗会话
     */
    public void stop() {
        running.set(false);
        battleState = BattleState.FINISHED;
        
        // 等待处理线程结束
        if (processingThread != null && processingThread.isAlive()) {
            try {
                processingThread.join(2000); // 最多等待2秒
            } catch (InterruptedException e) {
                logger.warn("Interrupted while waiting for battle thread to stop: {}", battleId, e);
                Thread.currentThread().interrupt();
            }
        }
        
        logger.info("Stopped battle session: {} ({})", battleId, battleName);
    }
    
    /**
     * 添加玩家到战斗
     * @param playerId 玩家ID
     * @param playerName 玩家名称
     * @return 是否成功添加
     */
    public boolean addPlayer(long playerId, String playerName) {
        if (battleState != BattleState.PREPARING) {
            logger.warn("Cannot add player {} to battle {} that is not in PREPARING state", 
                       playerName, battleId);
            return false;
        }
        
        if (players.containsKey(playerId)) {
            logger.warn("Player {} already exists in battle {}", playerName, battleId);
            return false;
        }
        
        BattlePlayer player = new BattlePlayer(playerId, playerName);
        players.put(playerId, player);
        
        logger.info("Added player {} to battle {}", playerName, battleId);
        return true;
    }
    
    /**
     * 从战斗中移除玩家
     * @param playerId 玩家ID
     * @return 是否成功移除
     */
    public boolean removePlayer(long playerId) {
        BattlePlayer player = players.remove(playerId);
        if (player != null) {
            logger.info("Removed player {} from battle {}", player.getPlayerName(), battleId);
            return true;
        }
        return false;
    }
    
    /**
     * 提交战斗消息到处理队列
     * @param playerId 玩家ID
     * @param messageId 消息ID
     * @param messageBytes 消息字节数组
     * @return 是否成功提交
     */
    public boolean submitMessage(long playerId, int messageId, byte[] messageBytes) {
        if (!running.get()) {
            logger.warn("Battle {} is not running, ignoring message: {} from player {}", 
                       battleId, messageId, playerId);
            return false;
        }
        
        if (!players.containsKey(playerId)) {
            logger.warn("Player {} is not in battle {}, ignoring message: {}", 
                       playerId, battleId, messageId);
            return false;
        }
        
        // 将消息加入队列
        BattleMessageContext messageContext = new BattleMessageContext(playerId, messageId, messageBytes);
        messageQueue.offer(messageContext);
        
        logger.debug("Submitted message {} from player {} to battle {} queue size: {}", 
                    messageId, playerId, battleId, messageQueue.size());
        
        return true;
    }
    
    /**
     * 开始战斗
     */
    public void startBattle() {
        if (players.size() < 2) {
            logger.warn("Cannot start battle {} with less than 2 players", battleId);
            return;
        }
        
        battleState = BattleState.IN_PROGRESS;
        logger.info("Battle {} ({}) started with {} players", battleId, battleName, players.size());
    }
    
    /**
     * 暂停战斗
     */
    public void pauseBattle() {
        if (battleState == BattleState.IN_PROGRESS) {
            battleState = BattleState.PAUSED;
            logger.info("Battle {} ({}) paused", battleId, battleName);
        }
    }
    
    /**
     * 恢复战斗
     */
    public void resumeBattle() {
        if (battleState == BattleState.PAUSED) {
            battleState = BattleState.IN_PROGRESS;
            logger.info("Battle {} ({}) resumed", battleId, battleName);
        }
    }
    
    /**
     * 处理战斗逻辑的主循环
     * 在专用的虚拟线程中运行
     */
    private void processBattleLogicLoop() {
        logger.info("Started battle logic processing loop for battle: {} ({}) in thread: {}", 
                   battleId, battleName, Thread.currentThread().getName());
        
        try {
            while (running.get() && !Thread.currentThread().isInterrupted()) {
                try {
                    // 处理队列中的消息
                    BattleMessageContext messageContext = messageQueue.poll();
                    if (messageContext != null) {
                        processBattleMessage(messageContext);
                    } else {
                        // 没有消息时短暂休眠，避免空转
                        Thread.sleep(1);
                    }
                    
                    // 处理战斗状态更新
                    if (battleState == BattleState.IN_PROGRESS) {
                        updateBattleState();
                    }
                    
                } catch (InterruptedException e) {
                    logger.info("Battle {} processing thread interrupted", battleId);
                    break;
                } catch (Exception e) {
                    logger.error("Error in battle {} processing loop", battleId, e);
                }
            }
        } finally {
            // 处理剩余消息
            while (!messageQueue.isEmpty()) {
                BattleMessageContext messageContext = messageQueue.poll();
                if (messageContext != null) {
                    try {
                        processBattleMessage(messageContext);
                    } catch (Exception e) {
                        logger.error("Error processing remaining message in battle: {}", battleId, e);
                    }
                }
            }
            
            logger.info("Stopped battle logic processing loop for battle: {} ({})", battleId, battleName);
        }
    }
    
    /**
     * 处理单个战斗消息
     * @param messageContext 消息上下文
     */
    private void processBattleMessage(BattleMessageContext messageContext) {
        long playerId = messageContext.getPlayerId();
        int messageId = messageContext.getMessageId();
        byte[] messageBytes = messageContext.getMessageBytes();
        
        try {
            // 在实际实现中，这里应该根据消息ID查找并执行相应的处理器
            logger.debug("Processing message {} from player {} in battle {}", 
                        messageId, playerId, battleId);
            
            // 示例：处理玩家移动消息
            // if (messageId == BattleMessageID.PLAYER_MOVE) {
            //     PlayerMoveMessage moveMessage = deserialize(messageBytes, PlayerMoveMessage.class);
            //     handlePlayerMove(playerId, moveMessage);
            // }
            
        } catch (Exception e) {
            logger.error("Error processing message {} from player {} in battle {}", 
                        messageId, playerId, battleId, e);
        }
    }
    
    /**
     * 更新战斗状态
     */
    private void updateBattleState() {
        // 在实际实现中，这里应该更新战斗状态，如计算伤害、移动等
        // 示例：检查战斗是否应该结束
        // if (checkBattleEnd()) {
        //     battleState = BattleState.FINISHED;
        //     handleBattleEnd();
        // }
    }
    
    // Getters
    public long getBattleId() {
        return battleId;
    }
    
    public String getBattleName() {
        return battleName;
    }
    
    public BattleState getBattleState() {
        return battleState;
    }
    
    public long getCreationTime() {
        return creationTime;
    }
    
    public long getCreateTime() {
        return creationTime;
    }
    
    public int getPlayerCount() {
        return players.size();
    }
    
    public int getMaxPlayers() {
        return maxPlayers;
    }
    
    public List<BattlePlayer> getPlayers() {
        return new ArrayList<>(players.values());
    }
    
    public int getQueueSize() {
        return messageQueue.size();
    }
    
    public boolean isRunning() {
        return running.get();
    }
    
    public Thread getProcessingThread() {
        return processingThread;
    }
}